using UnityEngine;
using WebSocketSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text;
using System;
using PimDeWitte.UnityMainThreadDispatcher;

public class GameController : MonoBehaviour
{
    private float rotationSpeed = 5.0f;
    private Color newColor = Color.red;

    public Transform cubeTransform;
    public GameObject[] enemyPrefabs;
    public GameObject targetCube;
    public List<GameObject> enemies = new List<GameObject>();
    public WebSocket webSocket;

    private void Start()
    {
        DontDestroyOnLoad(gameObject);
        webSocket = new WebSocket("ws://192.168.43.1:8083/websocket");
        webSocket.OnMessage += OnWebSocketMessage;
        webSocket.Connect();
        Debug.Log("WebSocket connected to ws://192.168.43.1:8083/websocket");

        if (enemyPrefabs != null && enemyPrefabs.Length > 0 && cubeTransform != null)
        {
            // Do additional initialization if needed
        }
        else
        {
            Debug.LogError("Check references in the Inspector.");
        }
    }

    void Update()
    {
        cubeTransform.Rotate(Vector3.up * rotationSpeed * Time.deltaTime);
    }

    private void OnWebSocketMessage(object sender, MessageEventArgs e)
    {
        string message = e.Data;
        string utf8Message = Encoding.UTF8.GetString(Encoding.Default.GetBytes(message));

        try
        {
            JObject jsonData = JObject.Parse(utf8Message);
            int messageType = Convert.ToInt32(jsonData["Type"]);

            switch (messageType)
            {
                case 1:
                case 3:
                case 5:
                    HandleUserAction(jsonData);
                    break;

                default:
                    Debug.Log("Unhandled message type: " + messageType);
                    break;
            }
        }
        catch (JsonReaderException ex)
        {
            Debug.LogError("Error parsing JSON: " + ex.Message);
        }

        if (!webSocket.IsAlive)
        {
            Debug.LogWarning("WebSocket connection closed, reconnecting...");
            webSocket.Connect();
            Debug.Log("WebSocket reco ws://192.168.43.1:8083/websocket");
        }
    }

    private void HandleUserAction(JObject jsonData)
    {
        UnityMainThreadDispatcher.Instance().Enqueue(() =>
        {
            Debug.Log("HandleUserAction Lambda executed");

            try
            {
                Debug.Log("HandleUserAction started");

                int userActionType = Convert.ToInt32(jsonData["Type"]);
                string userData = jsonData["Data"].ToString();
                JObject userObject = JObject.Parse(userData);

                switch (userActionType)
                {
                    case 3: // 加入游戏
                        Debug.Log("HandleUserAction: Player joined the game");

                        if (userObject != null && userObject["User"] != null && userObject["User"]["Nickname"] != null)
                        {
                            string username = userObject["User"]["Nickname"].ToString();
                            GameObject newEnemy = GenerateRandomEnemy(username);
                            enemies.Add(newEnemy);

                            Debug.Log("HandleUserAction: Player joined the game successfully");
                        }
                        else
                        {
                            Debug.LogError("Invalid user data in the message.");
                        }
                        break;

                    case 5: // 礼物是移动的run逻辑
                        Debug.Log("HandleUserAction: Gift is a moving gift (run logic)");

                        if (enemies.Count > 0 && userObject != null && userObject["User"] != null && userObject["User"]["Nickname"] != null)
                        {
                            string username = userObject["User"]["Nickname"].ToString();
                            string giftName = userObject["Gift"]["GiftName"].ToString();
                            Debug.Log(giftName);
                            foreach (var enemy in enemies)
                            {
                                string objectNameToFind = $"{enemy.name}_{username}";
                                Debug.Log(objectNameToFind);
                                GameObject foundEnemy = GameObject.Find(objectNameToFind);

                                if (foundEnemy != null)
                                {
                                    if (giftName == "小心心")
                                    {
                                        Animator animator = foundEnemy.GetComponent<Animator>();
                                        if (animator != null)
                                        {
                                            animator.SetTrigger("Run");
                                        }
                                        else
                                        {
                                            Debug.LogError("Animator component not found on enemy.");
                                        }
                                    }
                                    else
                                    {
                                        Debug.Log("Unhandled gift type: " + giftName);
                                    }
                                }
                                else
                                {
                                    Debug.LogError("Enemy with name " + objectNameToFind + " not found.");
                                }
                            }
                        }
                        else
                        {
                            Debug.LogError("Invalid user data or no current enemy available.");
                        }
                        break;

                    default:
                        Debug.Log("Unhandled UserActionType: " + userActionType);
                        break;
                }

                Debug.Log("HandleUserAction completed");
            }
            catch (Exception ex)
            {
                Debug.LogError("HandleUserAction error: " + ex.Message);
            }
        });
    }

    private GameObject GenerateRandomEnemy(string username)
    {
        if (targetCube != null && enemyPrefabs != null && enemyPrefabs.Length > 0)
        {
            Vector3 cubePosition = targetCube.transform.position;
            Vector2 randomOffset = UnityEngine.Random.insideUnitCircle * rotationSpeed;
            cubePosition += new Vector3(randomOffset.x, 0.0f, randomOffset.y);

            GameObject selectedPrefab = enemyPrefabs[UnityEngine.Random.Range(0, enemyPrefabs.Length)];
            GameObject enemy = Instantiate(selectedPrefab, cubePosition, Quaternion.identity);
            Rigidbody enemyRigidbody = enemy.AddComponent<Rigidbody>();
            enemyRigidbody.freezeRotation = true;

            enemy.name = $"{selectedPrefab.name}_{username}";

            Debug.Log("Enemy generated at: " + cubePosition + ", Username: " + username);

            return enemy;
        }
        else
        {
            Debug.LogError("Check references in the Inspector.");
            return null;
        }
    }

    private void OnDestroy()
    {
        if (webSocket != null && webSocket.IsAlive)
        {
            webSocket.Close();
        }
    }
}
